#define  _CRT_SECURE_NO_WARNINGS
#ifndef __MY_DATA__
#define __MY_DATA__

#include <unordered_map>
#include <sstream>
#include "util.hpp"

namespace cloud
{
	class DataManager
	{
	private:
		std::string _backup_file;//备份信息持久化存储文件
		std::unordered_map<std::string, std::string> _table;//<文件名，文件唯一标识符>
	public:
		DataManager(const std::string& backup_file) :_backup_file(backup_file)
		{
			InitLoad();
		}

		//将哈希表数据存入备份信息文件
		bool Storage()
		{
			// 1.获取所有备份信息
			std::stringstream ss;
			auto it = _table.begin();
			for (; it != _table.end(); ++it)
			{
				// 2.将所有信息进行指定持久化格式的组织
				ss << it->first << " " << it->second << "\n";
			}
			// 3.持久化存储
			FileUtil fu(_backup_file);
			fu.SetContent(ss.str());
			return true;
		}

		// 分割函数
		int Split(const std::string& str, const std::string& sep, std::vector<std::string>* arry)
		{
			int count = 0;
			size_t pos = 0;//sep位置
			size_t idx = 0;//查找起始位置
			while (1)
			{
				pos = str.find(sep, idx);
				if (pos == std::string::npos)
				{
					break;
				}
				if (pos == idx)
				{// 此时遇到连续的分隔符，跳过此次循环
					idx = pos + sep.size();
					continue;
				}
				std::string tmp = str.substr(idx, pos - idx);
				arry->push_back(tmp);
				count++;
				idx = pos + sep.size();
			}
			// 跳出循环后，还没有将最后一个字符串插入
			if (idx < str.size())
			{
				arry->push_back(str.substr(idx));
				count++;
			}
			return count;
		}


		bool InitLoad()
		{
			// 从文件中读取所有备份数据
			FileUtil fu(_backup_file);
			std::string body;
			fu.GetContent(&body);
			// 解析数据，放入哈希表
			std::vector<std::string> arry;
			Split(body, "\n", &arry);
			for (auto& a : arry)
			{
				// b.txt b.txt-34657-345636
				std::vector<std::string> tmp;
				Split(a, " ", &tmp);
				if (tmp.size() != 2)
				{
					continue;
				}
				_table[tmp[0]] = tmp[1];//_table[文件名]=文件唯一标识符;
			}
			return true;
		}



		bool Insert(const std::string& key, const std::string& val)
		{
			_table[key] = val;
			Storage();
			return true;
		}

		bool Update(const std::string& key, const std::string& val) {
			_table[key] = val;
			Storage();
			return true;
		}

		bool GetOneByKey(const std::string& key, std::string* val) {
			auto it = _table.find(key);
			if (it == _table.end()) {
				return false;
			}
			*val = it->second;
			return true;
		}
	};
}

#endif 
